<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
    <title>Magnet Demo</title>
    <style>
      body {
        margin: 0;
        height: 100vh;
        display: flex;
      }
      * { font-size: 3vmin; }
      #tool {
        margin: auto;
        padding: 1vmin;
        border: .1vmin solid #999;
        background-color: #eee;
        font-family: monospace;
        z-index: 1;
      }
      #container {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        display: flex;
        flex-flow: column;
      }
      input {
        width: 3vmin;
        height: 3vmin;
        outline: none;
        border: .1vmin solid #ccc;
        font-family: monospace;
        color: #666;
      }
      .row {
        display: flex;
        flex-flow: row;
        flex: 2 2;
      }
      .group {
        position: relative;
        border: .1vmin solid #999;
        box-sizing: content-box;
        overflow: hidden;
        flex: 2 2;
      }
      #lines {
        z-index: 1;
        pointer-events: none;
      }
      #lines >* {
        position: absolute;
        width: 1px;
        height: 1px;
        background-color: #999;
        opacity: 0;
      }
      #lines >.show { opacity: .5; }
      #lines .vert {
        transform: translateX(-50%);
        height: 100%;
      }
      #lines .hori {
        transform: translateY(-50%);
        width: 100%;
      }
      .block {
        position: absolute;
        overflow: auto;
      }
      .block input {
        position: absolute;
        top: 0;
        right: 0;
      }
    </style>
    <script src="../magnet.min.js"></script>
    <script>
      let NEAR_DISTANCE = 15;

      window.addEventListener('load', () => {
        let domContainer = document.getElementById('container');
        let domMask = document.getElementById('lines');
        let domHoriMagnet = domMask.querySelector('.hori');
        let domVertMagnet = domMask.querySelector('.vert');

        function genBlock(dom) {
          let rootWidth = (dom.innerWidth||dom.clientWidth);
          let rootHeight = (dom.innerHeight||dom.clientHeight);
          let width = Math.max(30, parseInt(Math.random()*rootWidth/2));
          let height = Math.max(30, parseInt(Math.random()*rootHeight/2));
          let block = document.createElement('span');
          block.style.width = (width+'px');
          block.style.height = (height+'px');
          block.style.top = (parseInt(Math.random()*(rootHeight-height))+'px');
          block.style.left = (parseInt(Math.random()*(rootWidth-width))+'px');
          block.style.backgroundColor = ('#'+[1, 2, 3].map(() => ('0'+parseInt(100+Math.random()*155).toString(16)).slice(-2)).join(''));
          block.style.opacity = (0.25+Math.random()*0.75);
          block.classList.add('block');
          return block;
        }

        let globalMagnet = new Magnet().distance(NEAR_DISTANCE);
        let magnets = [];
        Array.prototype.forEach.call(domContainer.querySelectorAll('.group'), function(dom) {
          let magnet = new Magnet().distance(NEAR_DISTANCE);
          let doms = [];
          for (let bInx=(2+parseInt(Math.random()*2)); 0<bInx; bInx--) {
            let block = genBlock(dom);
            let checkbox = document.createElement('input');
            checkbox.setAttribute('type', 'checkbox');
            checkbox.setAttribute('checked', '');
            checkbox.addEventListener('mousedown', (evt) => evt.stopPropagation());
            checkbox.addEventListener('change', function() {
              let block = this.parentNode;
              if (this.checked) {
                block.style.resize = 'none';
                magnet.add(block);
                doms.push(block);
              } else {
                block.style.resize = 'both';
                magnet.remove(block);
                doms.splice(doms.indexOf(block), 1);
              }
            });
            block.addEventListener('mousedown', function() {
              this.style.zIndex = 10;
            });
            block.addEventListener('click', function() {
              this.style.zIndex = 1;
              dom.appendChild(this);
            });
            block.addEventListener('dblclick', function() {
              let checkbox = this.querySelector('input[type=checkbox]');
              checkbox.checked = !checkbox.checked;
              if (checkbox.checked) {
                magnet.add(this);
                doms.push(this);
              } else {
                magnet.remove(this);
                doms.splice(doms.indexOf(this), 1);
              }
            });
            ['attract', 'unattract', 'attracted', 'unattracted'].forEach((type) => {
              block.addEventListener(type, function(e) {
                console.log(type, e);
              });
            });
            block.appendChild(checkbox);
            dom.appendChild(block);
            doms.push(block);
          }
          magnets.push({
            magnet: magnet,
            doms: doms
          });
        });
        function setAttract() {
          globalMagnet.clear();
          magnets.forEach((obj) => obj.magnet.clear());
          (() => {
            if (this.checked) {
              return [globalMagnet.add(magnets.map((obj) => obj.doms))];
            } else {
              return magnets.map((obj) => obj.magnet.add(obj.doms));
            }
          })().forEach((magnet) => magnet.on('magnetstart', () => {
            console.log('magnetstart');
          }).on('magnetend', () => {
            console.log('magnetend');
            domHoriMagnet.classList.remove('show');
            domVertMagnet.classList.remove('show');
          }).on('magnetchange', (e) => {
            let result = e.detail;
            console.log('magnetchange', result);
            domHoriMagnet.classList.remove('show');
            domVertMagnet.classList.remove('show');
            let resultX = result.x;
            let resultY = result.y;
            if (resultX) {
              domVertMagnet.style.left = (resultX.position+'px');
              domVertMagnet.classList.add('show');
            }
            if (resultY) {
              domHoriMagnet.style.top = (resultY.position+'px');
              domHoriMagnet.classList.add('show');
            }
          }));
        };
        document.getElementById('attract').addEventListener('change', setAttract);
        setAttract();
      });
    </script>
  </head>
  <body>
    <div id="lines">
      <span class="vert"></span>
      <span class="hori"></span>
    </div>
    <span id="tool">
      <input id="attract" type="checkbox" /><label for="attract">Attract other group magnets</label>
    </span>
    <div id="container">
      <div class="row">
        <div class="group"></div>
        <div class="group"></div>
      </div>
      <div class="row">
        <div class="group"></div>
        <div class="group"></div>
      </div>
    </div>
  </body>
</html>